package controller

import (
	"GoTime/utils"
	"GoTime/utils/conf"
	"bytes"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"mime/multipart"
	"net/http"
	"path"
	"strconv"
	"time"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"github.com/gin-gonic/gin"
)

func UploadImageBase64(c *gin.Context) {
	var (
		uploadPath string
		//data        []byte
		client    *oss.Client
		bucket    *oss.Bucket
		reqType   int64
		id        float64
		err       error
		buf       *bytes.Buffer
		imagebyte []byte
	)
	if uploadPath = c.PostForm("path"); uploadPath == "" {
		c.JSON(200, gin.H{"code": 201, "msg": "缺少参数path"})
		return
	}
	if reqType, err = strconv.ParseInt(c.PostForm("reqType"), 10, 64); err != nil {
		c.JSON(200, gin.H{"code": 201, "msg": "缺少参数type"})
		return
	}
	fileName := c.PostForm("img_name")
	sourceString := c.PostForm("file")
	imagebyte, err = base64.StdEncoding.DecodeString(sourceString)
	if err != nil {
		c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	buf = bytes.NewBuffer(imagebyte)
	if id, _, err = ImageUpToG(buf, uploadPath, fileName, reqType, c.PostForm("province"), c.PostForm("city")); err != nil {
		c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	fmt.Println("ad!!!!")
	ossEndpoint := conf.GetString("oss.endpoint")
	ossAccessId := conf.GetString("oss.access_id")
	ossAccessKey := conf.GetString("oss.access_key")
	ossBucket := conf.GetString("oss.bucket")
	ossWebsite := conf.GetString("oss.website")
	log.Println(ossEndpoint, ossAccessId, ossAccessKey, ossBucket, ossWebsite)
	// 上传到oss
	if client, err = oss.New(ossEndpoint, ossAccessId, ossAccessKey); err != nil {
		c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	if bucket, err = client.Bucket(ossBucket); err != nil {
		c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	// 构造文件名
	path.Ext(fileName)
	fileName = fmt.Sprintf("%s/%s/%.0f%s", uploadPath, time.Now().Format("20060102"), id, path.Ext(fileName))
	if err = bucket.PutObject(fileName, bytes.NewReader(imagebyte)); err != nil {
		c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
		return
	}

	c.JSON(200, gin.H{"code": 200, "msg": "上传照片成功", "data": gin.H{"PortraitCode": id, "ImageUrl": ossWebsite + fileName}})
	return
}

func UploadImage(c *gin.Context) {
	var (
		uploadPath string
		f          multipart.File
		h          *multipart.FileHeader
		data       []byte
		client     *oss.Client
		bucket     *oss.Bucket
		reqType    int64
		id         float64
		err        error
	)
	if uploadPath = c.PostForm("path"); uploadPath == "" {
		c.JSON(200, gin.H{"code": 201, "msg": "缺少参数path"})
		return
	}
	if reqType, err = strconv.ParseInt(c.PostForm("reqType"), 10, 64); err != nil {
		c.JSON(200, gin.H{"code": 201, "msg": "缺少参数type"})
		return
	}
	if f, h, err = c.Request.FormFile("file"); err != nil {
		c.JSON(200, gin.H{"code": 201, "msg": "缺少照片参数"})
		return
	}
	if id, data, err = ImageUpToG(f, uploadPath, h.Filename, reqType, c.PostForm("province"), c.PostForm("city")); err != nil {
		c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
		return
	}

	ossEndpoint := conf.GetString("oss.endpoint")
	ossAccessId := conf.GetString("oss.access_id")
	ossAccessKey := conf.GetString("oss.access_key")
	ossBucket := conf.GetString("oss.bucket")
	ossWebsite := conf.GetString("oss.website")
	//log.Println(ossEndpoint, ossAccessId, ossAccessKey, ossBucket, ossWebsite)
	// 上传到oss
	if client, err = oss.New(ossEndpoint, ossAccessId, ossAccessKey); err != nil {
		c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	if bucket, err = client.Bucket(ossBucket); err != nil {
		c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	// 构造文件名
	fileName := fmt.Sprintf("%s/%s/%.0f%s", uploadPath, time.Now().Format("20060102"), id, path.Ext(h.Filename))
	//fmt.Println(data, 222)
	if err = bucket.PutObject(fileName, bytes.NewReader(data)); err != nil {
		//c.Fail(500, err.Error())
		c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	c.JSON(200, gin.H{"code": 200, "msg": "上传照片成功", "data": gin.H{"PortraitCode": id, "ImageUrl": ossWebsite + fileName}})
	return
}

// ImageUpToG  文件上传到监管
func ImageUpToG(f io.Reader, imgtype, filename string, reqtype int64, province, city string) (float64, []byte, error) {
	var (
		part     io.Writer
		rsp      *http.Response
		data     []byte
		ret_byte []byte
		uri      string
		err      error
		id       float64
	)
	if data, err = ioutil.ReadAll(f); err != nil {
		return 0, nil, err
	}
	fmt.Println("asdasdasd")
	if uri, err = utils.Encrypt("imageup/"+imgtype, data, reqtype, province, city); err != nil {
		return 0, data, err
	}
	fmt.Println("!@!!!!!!")
	body := bytes.NewBuffer(nil)
	writer := multipart.NewWriter(body)
	if part, err = writer.CreateFormFile("file", filename); err != nil {
		return 0, data, err
	}
	fmt.Println("@@@@@###")
	part.Write(data)
	writer.Close()
	fmt.Println(uri)
	// fmt.Println(writer.FormDataContentType())
	// fmt.Println(body)
	if rsp, err = http.Post(uri, writer.FormDataContentType(), body); err != nil {
		return 0, data, err
	}
	defer rsp.Body.Close()
	if ret_byte, err = ioutil.ReadAll(rsp.Body); err != nil {
		fmt.Println(err.Error())
		return 0, data, err
	}
	fmt.Println(string(ret_byte), "1111111111111111111111")
	ret_map := make(map[string]interface{})
	if err = json.Unmarshal(ret_byte, &ret_map); err != nil {
		fmt.Println(err.Error())
		return 0, data, errors.New("监管平台服务异常")
	}
	fmt.Println("解析为json")
	fmt.Println(ret_map)
	switch ret_map["errorcode"].(type) {
	case float64:
		if ret_map["errorcode"].(float64) != 0 {
			return 0, data, errors.New(ret_map["message"].(string))
		}
	case string:
		if ret_map["errorcode"].(string) != "0" {
			return 0, data, errors.New(ret_map["message"].(string))
		}
	}
	if md, ok := ret_map["data"].(map[string]interface{}); ok {
		switch md["id"].(type) {
		case float64:
			fmt.Println(md["id"], "~~~~~~~~~~~~~~~~~~~~~~", md["id"].(float64))
			return md["id"].(float64), data, nil
		case string:
			id, _ = strconv.ParseFloat(md["id"].(string), 64)
			return id, data, nil
		}

	}
	return 0, data, errors.New("获取文件编号失败")
}
